Enable TSC-offsetting capability to ensure that VMX
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Sun, 23 Oct 2005 15:54:51 +0000 (16:54 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Sun, 23 Oct 2005 15:54:51 +0000 (16:54 +0100)
guest's TSC remains in sync with virtual-PIT interrupts.
This avoids the following message from full-virt Linux:
       "Losing too many ticks!
        TSC cannot be used as a timesource. =20
        Possible reasons for this are:
          You're running with Speedstep,
        ......"

Signed-off-by: Eddie Dong <eddie.dong@intel.com>
Signed-off-by: Edwin Zhai <edwin.zhai@intel.com>
xen/arch/x86/vmx_intercept.c
xen/arch/x86/vmx_io.c
xen/include/asm-x86/vmx.h
xen/include/asm-x86/vmx_virpit.h
xen/include/asm-x86/vmx_vmcs.h

index 4e9a1fe86d2cd19978b29eb173e875e25afb9881..0a3c168107d58502f7a16562f61a173d9d39ccf4 100644 (file)
@@ -254,6 +254,8 @@ void vmx_hooks_assist(struct vcpu *v)
                    vpit->init_val);
             vpit->period = 1000000;
         }
+         vpit->period_cycles = (u64)vpit->period * cpu_khz / 1000000L;
+         printk("VMX_PIT: guest freq in cycles=%lld\n",(long long)vpit->period_cycles);
 
         vpit->channel = ((p->u.data >> 24) & 0x3);
         vpit->first_injected = 0;
index 434d302209c819b804a9acf4401ad79b558aea8e..4ede995d8c891cc696a08c8ec57d3d1401191071 100644 (file)
@@ -799,6 +799,7 @@ static inline void
 interrupt_post_injection(struct vcpu * v, int vector, int type)
 {
     struct vmx_virpit *vpit = &(v->domain->arch.vmx_platform.vmx_pit);
+    u64    drift;
 
     switch(type)
     {
@@ -812,6 +813,13 @@ interrupt_post_injection(struct vcpu * v, int vector, int type)
                 vpit->pending_intr_nr--;
             }
             vpit->inject_point = NOW();
+            drift = vpit->period_cycles * vpit->pending_intr_nr;
+            drift = v->arch.arch_vmx.tsc_offset - drift;
+            __vmwrite(TSC_OFFSET, drift);
+
+#if defined (__i386__)
+            __vmwrite(TSC_OFFSET_HIGH, (drift >> 32));
+#endif
  
         }
         break;
index d16080cb1a56235302e4f1d601d04b9754ecf80b..445c24bb592248a9b2efaeed103c1cb99f2f84de 100644 (file)
@@ -65,6 +65,7 @@ extern unsigned int cpu_rev;
     CPU_BASED_MWAIT_EXITING | \
     CPU_BASED_MOV_DR_EXITING | \
     CPU_BASED_ACTIVATE_IO_BITMAP | \
+    CPU_BASED_USE_TSC_OFFSETING  | \
     CPU_BASED_UNCOND_IO_EXITING \
     )
 
index d0c758dd375a084aed9b5c473dc28991a6999e75..9539682d940dd703bb7f5f79a040d4ea763d16c6 100644 (file)
@@ -19,6 +19,7 @@
 struct vmx_virpit {
     /* for simulation of counter 0 in mode 2*/
     u32 period;                /* pit frequency in ns */
+    u64 period_cycles;                 /* pit frequency in cpu cycles */
     s_time_t scheduled;                 /* scheduled timer interrupt */
     unsigned int channel;  /* the pit channel, counter 0~2 */
     unsigned int pending_intr_nr; /* the couner for pending timer interrupts */
index f47daf8e092aacf5fc6c4669fd33dd6b6da4eefb..207289a59d780d03688517b746fbf3427cd1e644 100644 (file)
@@ -96,6 +96,7 @@ struct arch_vmx_struct {
     struct msr_state        msr_content;
     struct mmio_op          mmio_op;  /* MMIO */
     void                    *io_bitmap_a, *io_bitmap_b;
+    u64                     tsc_offset;
 };
 
 #define vmx_schedule_tail(next)         \